#include "fasttask.h"
#include <chrono>
#include <random>
#include <Qtdebug>
#include <QApplication>
#include <QDir>

#define LOOP_COUNT 50000

FastTask::FastTask(FastBufferHandler *handler) : m_handler(handler), m_logFile(nullptr)
{
    // qDebug() << "thread" << m_handler->id() << "created";
}

void FastTask::run()
{
    // qDebug() << "thread" << m_handler->id() << "start";
    QString logFilePath = qApp->applicationDirPath() + QString("/log/%1.log").arg(m_handler->id());
    QDir dir(qApp->applicationDirPath());
    if (!dir.exists("log"))
    {
        dir.mkdir("log");
    }
    m_logFile = new QFile(logFilePath);
    if (!m_logFile->open(QIODevice::WriteOnly | QIODevice::Text))
    {
        qDebug() << "open log file failed,task exit";
        return;
    }

    int i = 0;
    while (i++ < LOOP_COUNT)
    {
        if (m_handler->id() == 0)
        {
            qDebug() << "task progress:" << i << "/" << LOOP_COUNT;
        }
        taskLog(QString("thread[%2] loop[%1] send ").arg(i).arg(m_handler->id()));
        generateData();

        // 计时起点
        const std::chrono::time_point<std::chrono::steady_clock> sendBefore = std::chrono::steady_clock::now();
        sendData();
        recvData();
        // 计时终点
        const std::chrono::time_point<std::chrono::steady_clock> recvAfter = std::chrono::steady_clock::now();
        std::chrono::microseconds usCount = std::chrono::duration_cast<std::chrono::microseconds>(recvAfter - sendBefore);
        std::chrono::nanoseconds nsCount = std::chrono::duration_cast<std::chrono::nanoseconds>(recvAfter - sendBefore);

        // 打印本次循环日志信息
        taskLog(QString("%1 ns cost,recv ").arg(nsCount.count()));
        QVector<double> &buffer = m_handler->fastBuffer();
        taskLog(printVector(buffer));
        taskLog("\n");
        flushLog();
        m_handler->recordTimeout(nsCount.count());
        m_handler->waitDataInit();
    }
    taskLog(QString("thread:%1 finished").arg(m_handler->id()));
}

void FastTask::generateData()
{
    QVector<double> &buffer = m_handler->fastBuffer();
    // 使用随机设备生成随机种子
    std::random_device rd;
    // 初始化梅森旋转引擎，种子为随机设备生成的值
    std::mt19937 gen(rd());
    // 定义一个生成0到1之间double型随机数的分布
    std::uniform_real_distribution<> dis(0.0, 1.0);

    for (int i = 0; i < buffer.size(); i++)
    {
        // 生成一个随机double数值并存入buffer
        buffer[i] = dis(gen);
    }
    QString logStr = printVector(buffer);
    taskLog(logStr);
    taskLog("\n"); // 换行
    m_handler->readFinish();
    m_handler->sendData();
    m_handler->waitDataReady();
}

void FastTask::sendData()
{
}

void FastTask::recvData()
{
    m_handler->recvData();
}

void FastTask::taskLog(QString msg)
{
    m_logBuffer.append(msg);
}

void FastTask::flushLog()
{
    // qDebug().noquote() << m_logBuffer;
    m_logFile->write(m_logBuffer.toUtf8());
    m_logBuffer.clear();
}

QString FastTask::printVector(QVector<double> data)
{
    QString logStr;
    logStr.append(QString("data:["));
    for (double value : data)
    {
        logStr.append(QString("%1\t").arg(value, 8));
    }
    logStr.append("]");
    return logStr;
}
